package com.tuling.service.impl;

import com.tuling.common.Result;
import com.tuling.mapper.QuestionAnswerMapper;
import com.tuling.pojo.*;
import com.tuling.pojo.excel.QuestionAnswerExcel;
import com.tuling.pojo.vo.PersonQuestionAnswerVO;
import com.tuling.pojo.vo.QuestionAnswerVO;
import com.tuling.service.QuestionAnswerService;
import com.tuling.service.QuestionService;
import com.tuling.service.UserService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
public class QuestionAnswerServiceImpl implements QuestionAnswerService {

    @Resource
    private UserService userService;
    @Resource
    private QuestionAnswerMapper questionAnswerMapper;
    @Resource
    private QuestionService questionService;

    @Override
    public Result<Map<String, QuestionAnswerVO>> uploadAnswer(String userName, String password, String answer) {
        Assert.notNull(answer, "答案不能为空");
        Assert.notNull(userName, "用户名不能为空");
        Assert.notNull(password, "密码不能为空");
        Question cacheQuestion = questionService.getCacheQuestion();
        Assert.notNull(cacheQuestion, "缓存问题为空，请先获取问题");
        Long questionId = cacheQuestion.getId();
        // 获取ID，用户新增
        UserExample userExample = new UserExample();
        userExample.createCriteria().andNameEqualTo(userName).andPasswordEqualTo(password);
        List<User> users = userService.queryUser(userExample);
        if (CollectionUtils.isEmpty(users)) {
            return Result.fail("用户信息不存在");
        }
        User user = users.get(0);
        // 维护question_answer表（创建或修改）
        updateOrCreate(questionId, answer, user);
        // 获取其它组员答案
        Map<String, QuestionAnswerVO> result = getOtherPeopleAns(questionId);
        return Result.ok(result);
    }

    @Override
    public Result<List<QuestionAnswerExcel>> export(String userName, String password, String type) {
        Assert.notNull(userName, "用户名不能为空");
        Assert.notNull(password, "密码不能为空");
        // 获取用户信息
        UserExample userExample = new UserExample();
        userExample.createCriteria().andNameEqualTo(userName).andPasswordEqualTo(password);
        List<User> users = userService.queryUser(userExample);
        if (CollectionUtils.isEmpty(users)) {
            return Result.fail("查询用户信息失败");
        }
        User user = users.get(0);
        // 获取数据
        QuestionAnswerExample questionAnswerExample = new QuestionAnswerExample();
        QuestionAnswerExample.Criteria criteria = questionAnswerExample.createCriteria().andUserIdEqualTo(user.getId());
        if (StringUtils.isNotBlank(type)) {
            criteria.andTypeEqualTo(type);
        }
        List<QuestionAnswer> questionAnswers = questionAnswerMapper.selectByExampleWithBLOBs(questionAnswerExample);
        if (CollectionUtils.isEmpty(questionAnswers)) {
            return Result.fail("查询用户提交记录失败，请检查入参");
        }
        // 获取问题参考答案
        List<Long> questionIds = questionAnswers.stream().map(e -> e.getQuestionId()).collect(Collectors.toList());
        QuestionExample questionExample = new QuestionExample();
        questionExample.createCriteria().andIdIn(questionIds);
        Map<Long, Question> questionMap = questionService.queryByExample(questionExample).stream()
                .collect(Collectors.toMap(Question::getId, Function.identity(), (v1, v2) -> v2));
        // 拼接Excel模型
        List<QuestionAnswerExcel> needExport = new ArrayList<>();
        questionAnswers.forEach(questionAnswer -> {
            QuestionAnswerExcel questionAnswerExcel = new QuestionAnswerExcel();
            questionAnswerExcel.setName(user.getName());
            questionAnswerExcel.setType(questionAnswer.getType());
            questionAnswerExcel.setQuestionKey(questionMap.get(questionAnswer.getQuestionId()).getQuestionKey());
            questionAnswerExcel.setQuestionValue(questionMap.get(questionAnswer.getQuestionId()).getQuestionValue());
            questionAnswerExcel.setAnswerValue(questionAnswer.getAnswerValue());
            questionAnswerExcel.setScore(questionAnswer.getScore());
            questionAnswerExcel.setRemark(questionAnswer.getRemark());
            needExport.add(questionAnswerExcel);
        });
        return Result.ok(needExport);
    }

    private Map<String, QuestionAnswerVO> getOtherPeopleAns(Long questionId) {
        // 获取其它组员的答案并最终返回
        QuestionAnswerExample questionAnswerExample = new QuestionAnswerExample();
        questionAnswerExample.createCriteria().andQuestionIdEqualTo(questionId);
        // 用户ID为key，问题答案为value
        Map<Long, QuestionAnswer> longQuestionAnswerMap = questionAnswerMapper.selectByExampleWithBLOBs(questionAnswerExample).stream()
                .collect(Collectors.toMap(QuestionAnswer::getUserId, Function.identity(), (v1, v2) -> v2));
        // 将上方Map转换成用户名称为key，问题答案为value并返回
        // 根据userIds获取用户信息以id为key user为value
        Set<Long> longs = longQuestionAnswerMap.keySet();
        UserExample userExample = new UserExample();
        userExample.createCriteria().andIdIn(new ArrayList<>(longs));
        Map<Long, User> longUserMap = userService.queryUser(userExample).stream().collect(Collectors.toMap(User::getId, Function.identity()));
        // 拼接结果
        Map<String, QuestionAnswerVO> result = new HashMap<>();
        longQuestionAnswerMap.forEach((k, v) -> {
            // 循环体内局部变量增加Inner后缀
            User userInner = longUserMap.get(k);
            QuestionAnswerVO questionAnswerVO = new QuestionAnswerVO();
            questionAnswerVO.setAnswerValue(longQuestionAnswerMap.get(k).getAnswerValue());
            result.put(userInner.getName(), questionAnswerVO);
        });
        Question cacheQuestion = questionService.getCacheQuestion();
        QuestionAnswerVO questionAnswer = new QuestionAnswerVO();
        questionAnswer.setAnswerValue(cacheQuestion.getQuestionValue());
        result.put("参考答案", questionAnswer);
        return result;
    }

    private void updateOrCreate(Long questionId, String answer, User user) {
        // 验重
        QuestionAnswerExample questionAnswerExample = new QuestionAnswerExample();
        questionAnswerExample.createCriteria().andUserIdEqualTo(user.getId()).andQuestionIdEqualTo(questionId);
        List<QuestionAnswer> questionAnswers = questionAnswerMapper.selectByExample(questionAnswerExample);
        // 修改或新增
        if (CollectionUtils.isNotEmpty(questionAnswers)) {
            /*// 去掉修改功能，防止有人卡bug
            QuestionAnswer questionAnswer = questionAnswers.get(0);
            questionAnswer.setAnswerValue(answer);
            questionAnswerMapper.updateByPrimaryKeyWithBLOBs(questionAnswer);*/
        } else {
            Question cacheQuestion = questionService.getCacheQuestion();
            QuestionAnswer questionAnswer = new QuestionAnswer();
            questionAnswer.setQuestionId(questionId);
            questionAnswer.setAnswerValue(answer);
            questionAnswer.setUserId(user.getId());
            questionAnswer.setGmtCreated(new Date());
            questionAnswer.setGmtModified(new Date());
            questionAnswer.setType(cacheQuestion.getBelongSubject());
            questionAnswerMapper.insert(questionAnswer);
            // 如果是创建的话需要维护User表的最后回答时间和参与次数
            userService.updateTimeAndNum(user);
        }
    }

    /**
     * 组员答案评分备注
     */
    @Override
    public Result<PersonQuestionAnswerVO> score(Long id, Integer scoreNum, String remark, String useName, String password) {
        // 用户信息校验
        UserExample userExample = new UserExample();
        userExample.createCriteria().andNameEqualTo(useName).andPasswordEqualTo(password);
        List<User> users = userService.queryUser(userExample);
        if (CollectionUtils.isEmpty(users)) {
            return Result.fail("用户信息为空");
        }
        if (!users.get(0).getName().equals("天宇")&&!users.get(0).getName().equals("阿紫")) {
            return Result.fail("sorry，你娃还想评分卡bug？");
        }
        // 首次查询组员回答，然后在评分
        if (scoreNum == null) {
            // 从问题回答表中找出最近的一次没有评分的记录
            return Result.ok(getPersonQuestionAnswerVO());
        }
        // 验证账号密码，只允许master评分
        Assert.notNull(id, "questionAnswerId不能为空");
        Assert.notNull(scoreNum, "评分不能为空");
        QuestionAnswerExample questionAnswerExample = new QuestionAnswerExample();
        questionAnswerExample.createCriteria().andIdEqualTo(id);
        List<QuestionAnswer> questionAnswers = questionAnswerMapper.selectByExample(questionAnswerExample);
        if (CollectionUtils.isEmpty(questionAnswers)) {
            return Result.fail("查询questionAnswer表信息失败");
        }
        QuestionAnswer questionAnswer = questionAnswers.get(0);
        if (questionAnswer.getScore() != null) {
            return Result.ok(getPersonQuestionAnswerVO());
        }
        questionAnswer.setScore(scoreNum);
        if (StringUtils.isNotBlank(remark)) {
            questionAnswer.setRemark(remark);
        }
        // 跟新评分和评价
        questionAnswerMapper.updateByPrimaryKey(questionAnswer);
        // 从问题回答表中找出最近的一次没有评分的记录
        return Result.ok(getPersonQuestionAnswerVO());
    }

    private PersonQuestionAnswerVO getPersonQuestionAnswerVO() {
        QuestionAnswerExample otherGroupExample = new QuestionAnswerExample();
        otherGroupExample.createCriteria().andScoreIsNull();
        List<QuestionAnswer> otherGroup = questionAnswerMapper.selectByExampleWithBLOBs(otherGroupExample);
        if (CollectionUtils.isEmpty(otherGroup)) {
            throw new RuntimeException("暂无其它人员需要评分");
        }
        QuestionAnswer qa = otherGroup.get(0);
        QuestionExample questionExample = new QuestionExample();
        questionExample.createCriteria().andIdEqualTo(qa.getQuestionId());
        Question question = questionService.queryByExample(questionExample).get(0);
        PersonQuestionAnswerVO personQuestionAnswerVO = new PersonQuestionAnswerVO();
        personQuestionAnswerVO.setAnswerValue(qa.getAnswerValue());
        personQuestionAnswerVO.setQuestionValue(question.getQuestionValue());
        personQuestionAnswerVO.setQuestionKey(question.getQuestionKey());
        personQuestionAnswerVO.setId(qa.getId());
        return personQuestionAnswerVO;
    }


    @Override
    public Result<List<QuestionAnswerExcel>> dailyPersonExport(String parse) {
        QuestionAnswerExample questionAnswerExample = new QuestionAnswerExample();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:ss:mm");
        String start = parse + " 00:00:00";
        String end = parse + " 23:59:59";
        try {
            questionAnswerExample.createCriteria().andGmtCreatedBetween(simpleDateFormat.parse(start), simpleDateFormat.parse(end));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        List<QuestionAnswer> questionAnswers = questionAnswerMapper.selectByExampleWithBLOBs(questionAnswerExample);
        if (CollectionUtils.isEmpty(questionAnswers)) {
            return Result.fail("暂时没有人回答");
        }
        Map<Long, String> userMap = userService.queryUser(new UserExample()).stream().collect(Collectors.toMap(User::getId, User::getName));
        Map<Long, Question> questionMap = questionService.queryByExample(new QuestionExample()).stream().collect(Collectors.toMap(Question::getId, Function.identity()));
        List<QuestionAnswerExcel> needExport = new ArrayList<>();
        questionAnswers.forEach(questionAnswer -> {
            QuestionAnswerExcel questionAnswerExcel = new QuestionAnswerExcel();
            questionAnswerExcel.setName(userMap.get(questionAnswer.getUserId()));
            questionAnswerExcel.setType(questionAnswer.getType());
            questionAnswerExcel.setQuestionKey(questionMap.get(questionAnswer.getQuestionId()).getQuestionKey());
            questionAnswerExcel.setQuestionValue(questionMap.get(questionAnswer.getQuestionId()).getQuestionValue());
            questionAnswerExcel.setAnswerValue(questionAnswer.getAnswerValue());
            questionAnswerExcel.setScore(questionAnswer.getScore());
            questionAnswerExcel.setRemark(questionAnswer.getRemark());
            needExport.add(questionAnswerExcel);
        });
        return Result.ok(needExport);
    }
}
